<?php
/**
 * 装饰器模式的使用场景：
 * 1.在动作周期里，在某个点上存在多个可选的自定义的内容，使用装饰器来将这些自定义内容放在外面实现，这样就可以在需要装饰器的时候任意加上即可
 */

namespace App\DesignPattern\Decorator;

use App\DesignPattern\Decorator\WriterDecorator;


class Writer
{
    private $decorators =  [];

    public function addDecorator(WriterDecorator $decorator)
    {
        $this->decorators[] = $decorator;
    }

    private function beforeWrite()
    {
        foreach ($this->decorators as $decorator)
        {
            $decorator->beforeWrite();
        }
    }

    private function afterWrite()
    {
        //装饰器遵循后进先出原则，所以需要反转下$decorators
        $decorators = array_reverse($this->decorators);
        foreach ($decorators as $decorator)
        {
            $decorator->afterWrite();
        }
    }

    public function write()
    {
        $this->beforeWrite();
        echo '我是个作家，我要写点东西<br/>';
        $this->afterWrite();
    }
}